﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MultiFasta2Fasta
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: MultiFasta2Fasta <fasta file> [/i]");
                Console.WriteLine("/i - ignore errors");
                return;
            }
            try
            {
                string mFastaFile = args[0];
                bool ignoreErrors = args.Contains("/i");
                string res = SplitFastaFile(mFastaFile, ignoreErrors);
                Console.WriteLine(res);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            } 
            Console.ReadKey();
        }

        private static string SplitFastaFile(string mFastaFile, bool ignoreErrors)
        {
            string res = "Success";

            if (!File.Exists(mFastaFile))
            {
                return "File not found: " + mFastaFile;
            }

            string currFolder = Path.GetDirectoryName(mFastaFile);
            string newFolder = Path.GetFileNameWithoutExtension(mFastaFile);

            using (FileStream fs = new FileStream(mFastaFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            using (TextReader faReader = new StreamReader(fs))
            {
                string line = faReader.ReadLine();
                if (!line.StartsWith(">") && !ignoreErrors)
                {
                    res = "Probably wrong file structure. To ignore use flag /i";
                    return res;
                }

                if (ignoreErrors)
                { // skip a few lines till ">"
                    bool structOK = false;
                    for (int i = 0; i < 10; i++)
                    {
                        line = faReader.ReadLine();
                        if (line.StartsWith(">"))
                        {
                            structOK = true;
                            break;
                        }
                    }
                    if (!structOK)
                    {
                        res = "Wrong file structure";
                        return res;
                    }
                }

                string partFileName;
                string oneFastaFileName;
                bool nextPart = false;

                string fullNewFolder = Path.Combine(currFolder, newFolder);
                if (!Directory.Exists(fullNewFolder))
                {
                    Directory.CreateDirectory(fullNewFolder);
                }

                while (!string.IsNullOrEmpty(line) && !nextPart)
                {
                    partFileName = line.TrimStart('>');
                    oneFastaFileName = Path.Combine(fullNewFolder, ProperFileName(partFileName));
                    using (TextWriter write = new StreamWriter(oneFastaFileName))
                    {
                        Console.Write(Path.GetFileName(oneFastaFileName));
                        write.WriteLine(line);
                        line = faReader.ReadLine();
                        while (!string.IsNullOrEmpty(line) && !nextPart)
                        {
                            if (line.StartsWith(">"))
                            {
                                nextPart = true;
                                break;
                            }
                            write.WriteLine(line);
                            line = faReader.ReadLine();
                        }
                    }
                    Console.WriteLine(" Done");
                    nextPart = false;
                }
            }

            return res;
        }

        private static string ProperFileName(string partName)
        {
            string fileName = partName;
            foreach (char c in System.IO.Path.GetInvalidFileNameChars())
            {
                fileName = fileName.Replace(c, '_');
            }
            return fileName + ".fa";
        }
    }
}
